package com.ecarx.vhaltests.hy11.testcases.system.windowdoorlock;

import static android.car.VehiclePropertyIds.WINDOW_POS;

import android.car.VehicleAreaWindow;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * [SW_FC_009_016]Vehicle车窗-天窗遮阳帘控制
 */

public class WindowPosTest extends VhalUnitTestBase {
    private static final String TAG = "WindowPosTest";
    private static int halValueTop2;
    private static int halStatusTop2;

    final static Object lockTop2 = new Object();
    private static final IpcpClient ipcpClient = new IpcpClient();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, WINDOW_POS, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }


    @Test
    public void testWindowPosNotAvail() {
        setWindowPosNotAvail();
        lockWaitTop2();
        Assert.assertEquals(halStatusTop2, 1);
        testWindowPosNotAvailTop2();
    }

    @Test
    public void testWindowPosAvail() {
        setWindowPosAvail();
        lockWaitTop2();
        Assert.assertEquals(halStatusTop2, 0);
        testWindowPosIsAvailTop2();
    }


    @Test
    public void testWindowPosTop2OpenFull() {
        setWindowPosAvail();
        setWindowPosValue(100);
        lockWaitTop2();
        Assert.assertEquals(halValueTop2, 100);
        Assert.assertEquals(halStatusTop2, 0);
        testWindowPosValue(VehicleAreaWindow.WINDOW_ROOF_TOP_2, 100);
    }

    @Test
    public void testWindowPosTop2CloseFull() {
        setWindowPosAvail();
        setWindowPosValue(0);
        lockWaitTop2();
        Assert.assertEquals(halValueTop2, 0);
        Assert.assertEquals(halStatusTop2, 0);
        testWindowPosValue(VehicleAreaWindow.WINDOW_ROOF_TOP_2, 0);
    }

    @Test
    public void testWindowPosTop2CloseHalf1() {
        setWindowPosAvail();
        setWindowPosValue(50);
        lockWaitTop2();
        Assert.assertEquals(halValueTop2, 52);
        Assert.assertEquals(halStatusTop2, 0);
        testWindowPosValue(VehicleAreaWindow.WINDOW_ROOF_TOP_2, 52);
    }

    @Test
    public void testWindowPosTop2CloseHalf2() {
        setWindowPosAvail();
        setWindowPosValue(52);
        lockWaitTop2();
        Assert.assertEquals(halValueTop2, 52);
        Assert.assertEquals(halStatusTop2, 0);
        testWindowPosValue(VehicleAreaWindow.WINDOW_ROOF_TOP_2, 52);
    }




    public void testWindowPosValue(int areaId, int value) {
        int halValue = mCarPropertyMgr.getIntProperty(WINDOW_POS, areaId);
        Assert.assertEquals(halValue, value);
    }

    public void setWindowPosValue( int value) {
        setWindowMoving();
        mCarPropertyMgr.setIntProperty(WINDOW_POS, VehicleAreaWindow.WINDOW_ROOF_TOP_2, value);
    }

    public void testWindowPosIsAvailTop2() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(WINDOW_POS, VehicleAreaWindow.WINDOW_ROOF_TOP_2);
        Assert.assertTrue(isAvail);
    }


    public void testWindowPosNotAvailTop2() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(WINDOW_POS, VehicleAreaWindow.WINDOW_ROOF_TOP_2);
        Assert.assertFalse(isAvail);
    }


    public void lockWaitTop2() {
        try {
            synchronized (lockTop2) {
                lockTop2.wait(2000);
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                Log.d(TAG, "WINDOW_POS onChangeEvent value:propertyId" + carPropertyValue.getPropertyId() + ",value:" + carPropertyValue.getValue());
                Log.d(TAG, "WINDOW_POS onChangeEvent Status" + carPropertyValue.getStatus());
                Log.d(TAG, "WINDOW_POS onChangeEvent areaId" + carPropertyValue.getAreaId());

                halValueTop2 = (int) carPropertyValue.getValue();
                halStatusTop2 = carPropertyValue.getStatus();
                Log.d("【test】", "WINDOW_POS onChangeEvent halValueTop2：" + halValueTop2);
                synchronized (lockTop2) {
                    lockTop2.notify();
                }

            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {

        }
    };

    public void setWindowPosAvail() {
        setCarConfig(2);
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);
        delay();
    }

    public void setWindowPosNotAvail() {
        setCarConfig(6);
        setCEM(VehicleConstants.CAR_MODE_CRASH,VehicleConstants.USG_MODE_ABANDON);
        delay();
    }

    private static void setConfig() {
        // HY11 car mode & usage mode 信号对应 ECU 为 CEM
        int cemSvcId = 37;
        int[] cemOperIds = {999};
        // carconfig 对应 Service ID & Operation ID
        int ccSvcId = 135;
        int[] ccOperIds = {200};
        int cdmSvcId = 36;
        int[] cdmOperIds = {999};

        boolean retCem = ipcpClient.setConfig(cemSvcId, cemOperIds);
        Assert.assertTrue(retCem);

        boolean retCc = ipcpClient.setConfig(ccSvcId, ccOperIds);
        Assert.assertTrue(retCc);

        boolean retCdm = ipcpClient.setConfig(cdmSvcId, cdmOperIds);
        Assert.assertTrue(retCdm);
    }

    public void setCEM(int carMode, int usgMode) {
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1CarModSts1","vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {carMode, usgMode};
        boolean cemResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemResult);
        delay();
    }

    public void setCarConfig(int carConfigValue) {
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {177};
        int[] values = {carConfigValue};
        boolean ccResult = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccResult);
        delay();
    }

    public void setWindowMoving() {
        IpcpClient ipcpClient = new IpcpClient();
        int cdmSvcId = 36;
        int cdmOperId = 999;
        int sunCurtMvngSts = 1;

        String[] cdms = {"sunCurtMvngSts"};
        int[] cdmValues = {sunCurtMvngSts};
        boolean dd = ipcpClient.setCDMSignal(cdmSvcId, cdmOperId, cdms, cdmValues);
        Assert.assertTrue(dd);
        delay();
    }

}
